package com.xbongbong.pro.statistics.service.impl;

import com.xbongbong.config.DataSource;
import com.xbongbong.config.DataSourceNames;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.xbongbong.config.DataSource;
import com.xbongbong.config.DataSourceNames;
import com.xbongbong.paas.domain.dao.PaasFormPaasSubDataDao;
import com.xbongbong.paas.domain.entity.ext.CkPaasFormDataEntityExt;
import com.xbongbong.paas.enums.bi.XbbTableRefEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.pro.domain.dao.CkPaasFormDataDao;
import com.xbongbong.pro.statistics.service.CkPaasFormDataService;
import com.xbongbong.saas.domain.dao.OtherExpenseDao;
import com.xbongbong.saas.domain.dao.OtherIncomeDao;
import com.xbongbong.saas.domain.dao.WorkOrderFlowUserDao;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.model.CkPaasFormDataModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述信息
 *
 * @ClassName CkPaasFormDataServiceImpl
 * @Author 梁鲁江
 * 创建时间 2021/10/15 16:08
 * 修改时间  2021/10/15 16:08
 **/
@Service("ckPaasFormDataService")
@Slf4j
public class CkPaasFormDataServiceImpl implements CkPaasFormDataService {
    @Resource
    private CkPaasFormDataModel ckPaasFormDataModel;
    @Resource
    private WorkOrderFlowUserDao workOrderFlowUserDao;
    @Resource
    private OtherIncomeDao otherIncomeDao;
    @Resource
    private OtherExpenseDao otherExpenseDao;
    @Resource
    private PaasFormPaasSubDataDao paasFormPaasSubDataDao;
    @Resource
    private CkPaasFormDataDao ckPaasFormDataDao;

    @DataSource(DataSourceNames.CK_DATA)
    @Override
    public List<CkPaasFormDataEntityExt> findEntitys(Map<String, Object> entity) {
        //TODO SQL的预校验
        return ckPaasFormDataModel.findEntitys(entity);
    }
    @DataSource(DataSourceNames.CK_DATA)
    @Override
    public List<CkPaasFormDataEntityExt> findEntitysBySql(String sql) {
        return ckPaasFormDataModel.findEntitysBySql(sql);
    }
    @DataSource(DataSourceNames.CK_DATA)
    @Override
    public Integer countBySql(String sql) {
        return ckPaasFormDataModel.countBySql(sql);
    }
    @DataSource(DataSourceNames.MYSQL_DATA)
    @Override
    public Integer countBySqlMySql(String sql) {
        return ckPaasFormDataModel.countBySql(sql);
    }

    @DataSource(DataSourceNames.CK_DATA)
    @Override
    public void insertBatch(List list, Integer businessType) throws XbbException {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum){
            case WORK_ORDER_TEAM:
                workOrderFlowUserDao.insertBatchCK(list);
                break;
            case OTHER_INCOME:
                otherIncomeDao.insertBatchCK(list);
                break;
            case OTHER_EXPENSE:
                otherExpenseDao.insertBatchCK(list);
                break;
            case OTHER_EXPENSE_SUBFORM:
            case OTHER_INCOME_SUBFORM:
                XbbTableRefEnum xbbTableRefEnum = XbbTableRefEnum.getByCode(businessType);
                paasFormPaasSubDataDao.insertBatchCK(list,xbbTableRefEnum.getTableName());
                break;
            default:
                break;
        }
    }


    @DataSource(DataSourceNames.CK_DATA)
    @Override
    public void insertBatch(List list, List<String> columns, String tableName) throws XbbException {
        List<Map<String, Object>> listFinal = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(list)) {
            for (Object o : list) {
                //需要有序 表字段与值一一对应
                Map<String, Object> objectObjectHashMap = new LinkedHashMap<>();
                JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(o));
                for (String column : columns) {
                    if (!column.contains("_")) {
                        objectObjectHashMap.put(column, handleObject(jsonObject.get(column)));
                    } else {
                        String[] s = column.split("_");
                        StringBuilder stringBuilder = new StringBuilder();
                        stringBuilder.append(s[0]);
                        for (int i = 1; i < s.length; i++) {
                            stringBuilder.append(s[i].substring(0, 1).toUpperCase()).append(s[i].substring(1));
                        }
                        objectObjectHashMap.put(stringBuilder.toString(), handleObject(jsonObject.get(stringBuilder.toString())));
                    }
                }
                listFinal.add(objectObjectHashMap);
            }
        }
        try {
            insertBatchCommonCK(listFinal, tableName, columns);
        } catch (Exception e) {
            List<Integer> listIds = new ArrayList<>();
            for (Map<String, Object> x : listFinal) {
                listIds.add((Integer) x.get("id"));
            }
            log.error("表" + tableName + "数据格式错误，插入失败" + listIds);
        }
    }

    @DataSource(DataSourceNames.CK_DATA)
    @Override
    public void insertBatchCommonCK(List<Map<String, Object>> list, String tableName, List<String> column) {
        ckPaasFormDataDao.insertBatchCommonCK(list,tableName,column);
    }
    @DataSource(DataSourceNames.CK_DATA)
    @Override
    public List<String> getColumnNameByTableName(String tableName) {
        return ckPaasFormDataDao.getColumnNameByTableName(tableName);
    }

    public Object handleObject(Object ob){
        if (ob instanceof Number ){
            return ob;
        }else if(ob == null) {
            return "null";
        }else if(ob instanceof JSONObject){
            return "'" + formatJson(ob) + "'";
        }else {
            if (ob.toString().contains("'")){
                String replace = ob.toString().replace("'", "");
                return "'" + replace + "'";
            }
            return "'" + handleString(ob)  + "'";
        }
    }

    public Object handleString(Object ob) {
        if (ob instanceof JSONObject) {
            if (ob.toString().contains("#{")) {
                ob = JSONObject.parseObject(ob.toString().replace("#{", "#-{"));
            }
            if (ob.toString().contains("${")) {
                ob = JSONObject.parseObject(ob.toString().replace("${", "$-{"));
            }
        } else {
            if (ob.toString().contains("#{")) {
                ob = ob.toString().replace("#{", "#-{");
            }
            if (ob.toString().contains("${")) {
                ob = ob.toString().replace("${", "$-{");
            }
        }
        return ob;
    }
    //转义jsonObject为带\字符串
    public String formatJson(Object json){
        if (null == json) {
            return "{}";
        }
        json = handleString(json);
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setPrettyPrinting();
        Gson gson = gsonBuilder.create();
        return gson.toJson(json);
    }

    public String handlerColumn(String column){
        if (!column.contains("_")) {
            return column;
        }else {
            String[] s = column.split("_");
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(s[0]);
            for (int i = 1; i < s.length; i++) {
                stringBuilder.append(s[i].substring(0, 1).toUpperCase()).append(s[i].substring(1));
            }
            return stringBuilder.toString();
        }
    }
    public void handleSuper(Object object,Class<?> aClass,JSONObject json) throws InstantiationException, IllegalAccessException, IntrospectionException, InvocationTargetException, NoSuchMethodException {
        boolean flag = true;
        while (flag) {
            Class<?> superclass = aClass.getSuperclass();
            if (superclass != null) {
                Field[] fields = aClass.getDeclaredFields();
                for (Field declaredField : fields) {
                    declaredField.setAccessible(true);
                    String attributeName = declaredField.getName();
                    if (attributeName.equals("serialVersionUID")) {
                        continue;
                    }
                    Boolean fl = true;
                    // 1.根据属性名称就可以获取其get方法
                    String getMethodName = "get"
                            + attributeName.substring(0, 1).toUpperCase()
                            + attributeName.substring(1);
                    Method method = aClass.getMethod(getMethodName);
                    Object invoke = method.invoke(object);
                    if (null == invoke) {
                        fl = false;
                    }
                    if (fl) {
                        json.put(attributeName, invoke);
                    } else {
                        json.put(attributeName, null);
                    }
                }
                aClass = superclass;
                handleSuper(object,aClass,json);
            } else {
                flag = false;
            }
        }

    }
}
